#include <stdio.h>
#include <stdbool.h>
#include <alsa/asoundlib.h>

//设置音频采集通道函数
//card：声卡名称
//selem：控制项名称
//enable：开关状态
int set_capture_channel(const char *card, const char *selem, bool enable) {
    int err;
    snd_mixer_t *handle;
    snd_mixer_elem_t *elem;
    snd_mixer_selem_id_t *sid;

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem);

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0) {
        fprintf(stderr, "snd_mixer_open error: %s\n", snd_strerror(err));
        return err;
    }

    // 附加混音器到卡
    if ((err = snd_mixer_attach(handle, card)) < 0) {
        fprintf(stderr, "snd_mixer_attach error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
        fprintf(stderr, "snd_mixer_selem_register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0) {
        fprintf(stderr, "snd_mixer_load error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 找到简单元素
    elem = snd_mixer_find_selem(handle, sid);
    if (!elem) {
        fprintf(stderr, "snd_mixer_find_selem error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return -1;
    }

    // 设置捕获开关
    if ((err = snd_mixer_selem_set_capture_switch_all(elem, enable ? 1 : 0)) < 0) {
        fprintf(stderr, "snd_mixer_selem_set_capture_switch_all error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);
    return 0;
}

//设置音频回放通道函数
//card：声卡名称
//selem：控制项名称
//enable：开关状态
int set_playback_channel(const char *card, const char *selem, bool enable) {
    int err;
    snd_mixer_t *handle;
    snd_mixer_elem_t *elem;
    snd_mixer_selem_id_t *sid;

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem);

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0) {
        fprintf(stderr, "snd_mixer_open error: %s\n", snd_strerror(err));
        return err;
    }

    // 附加混音器到卡
    if ((err = snd_mixer_attach(handle, card)) < 0) {
        fprintf(stderr, "snd_mixer_attach error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
        fprintf(stderr, "snd_mixer_selem_register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0) {
        fprintf(stderr, "snd_mixer_load error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 找到简单元素
    elem = snd_mixer_find_selem(handle, sid);
    if (!elem) {
        fprintf(stderr, "snd_mixer_find_selem error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return -1;
    }

    // 设置回放开关
    if ((err = snd_mixer_selem_set_playback_switch_all(elem, enable ? 1 : 0)) < 0) {
        fprintf(stderr, "snd_mixer_selem_set_playback_switch_all error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);
    return 0;
}

//获取音频采集音量函数
//card：声卡名称
//selem：控制项名称
//enable：开关状态
//返回值：volume
int get_capture_volume(const char *card, const char *selem){
    int err;
    long volume = 0;
    snd_mixer_t *handle;
    snd_mixer_elem_t *elem;
    snd_mixer_selem_id_t *sid;

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem);

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0) {
        fprintf(stderr, "snd_mixer_open error: %s\n", snd_strerror(err));
        return err;
    }

    // 附加混音器到卡
    if ((err = snd_mixer_attach(handle, card)) < 0) {
        fprintf(stderr, "snd_mixer_attach error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
        fprintf(stderr, "snd_mixer_selem_register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0) {
        fprintf(stderr, "snd_mixer_load error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 找到简单元素
    elem = snd_mixer_find_selem(handle, sid);
    if (!elem) {
        fprintf(stderr, "snd_mixer_find_selem error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return -1;
    }

    // 获取采集通道音量
    if ((err = snd_mixer_selem_get_capture_volume(elem, 0, &volume)) < 0) {
        fprintf(stderr, "snd_mixer_selem_get_capture_volume error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);
    
    //返回音量
    return volume;
}

//获取音频回放音量函数
//card：声卡名称
//selem：控制项名称
//enable：开关状态
//返回值：volume
int get_playback_volume(const char *card, const char *selem){
    int err;
    long volume = 0;
    snd_mixer_t *handle;
    snd_mixer_elem_t *elem;
    snd_mixer_selem_id_t *sid;

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem);

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0) {
        fprintf(stderr, "snd_mixer_open error: %s\n", snd_strerror(err));
        return err;
    }

    // 附加混音器到卡
    if ((err = snd_mixer_attach(handle, card)) < 0) {
        fprintf(stderr, "snd_mixer_attach error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
        fprintf(stderr, "snd_mixer_selem_register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0) {
        fprintf(stderr, "snd_mixer_load error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 找到简单元素
    elem = snd_mixer_find_selem(handle, sid);
    if (!elem) {
        fprintf(stderr, "snd_mixer_find_selem error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return -1;
    }

    // 获取回放通道音量
    if ((err = snd_mixer_selem_get_playback_volume(elem, 0, &volume)) < 0) {
        fprintf(stderr, "snd_mixer_selem_get_playback_volume error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);
    
    //返回音量
    return volume;
}

//设置音频采集音量函数
//card：声卡名称
//selem：控制项名称
//enable：开关状态
//volume：设置音量
int set_capture_volume(const char *card, const char *selem, long volume) {
    int err;
    snd_mixer_t *handle;
    snd_mixer_elem_t *elem;
    snd_mixer_selem_id_t *sid;

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem);

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0) {
        fprintf(stderr, "snd_mixer_open error: %s\n", snd_strerror(err));
        return err;
    }

    // 附加混音器到卡
    if ((err = snd_mixer_attach(handle, card)) < 0) {
        fprintf(stderr, "snd_mixer_attach error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
        fprintf(stderr, "snd_mixer_selem_register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0) {
        fprintf(stderr, "snd_mixer_load error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 找到简单元素
    elem = snd_mixer_find_selem(handle, sid);
    if (!elem) {
        fprintf(stderr, "snd_mixer_find_selem error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return -1;
    }

    long min = 0, max = 63;
    if ((err = snd_mixer_selem_set_capture_volume_range(elem, min, max)) < 0) {
        fprintf(stderr, "snd_mixer_selem_set_capture_volume_range error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }
    if(volume < min) volume = min;
    if(volume > max) volume = max;

    // 设置采集通道音量
    if ((err = snd_mixer_selem_set_capture_volume_all(elem, volume)) < 0) {
        fprintf(stderr, "snd_mixer_selem_set_capture_volume_all error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);
    return volume;
}

//设置音频回放音量函数
//card：声卡名称
//selem：控制项名称
//enable：开关状态
//volume：设置音量
int set_playback_volume(const char *card, const char *selem, long volume) {
    int err;
    snd_mixer_t *handle;
    snd_mixer_elem_t *elem;
    snd_mixer_selem_id_t *sid;

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem);

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0) {
        fprintf(stderr, "snd_mixer_open error: %s\n", snd_strerror(err));
        return err;
    }

    // 附加混音器到卡
    if ((err = snd_mixer_attach(handle, card)) < 0) {
        fprintf(stderr, "snd_mixer_attach error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
        fprintf(stderr, "snd_mixer_selem_register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0) {
        fprintf(stderr, "snd_mixer_load error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 找到简单元素
    elem = snd_mixer_find_selem(handle, sid);
    if (!elem) {
        fprintf(stderr, "snd_mixer_find_selem error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return -1;
    }

    long min = 0, max = 63;
    if ((err = snd_mixer_selem_set_playback_volume_range(elem, min, max)) < 0) {
        fprintf(stderr, "snd_mixer_selem_set_playback_volume_range error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }
    if(volume < min) volume = min;
    if(volume > max) volume = max;

    // 设置回放通道音量
    if ((err = snd_mixer_selem_set_playback_volume_all(elem, volume)) < 0) {
        fprintf(stderr, "snd_mixer_selem_set_playback_volume_all error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);
    return volume;
}

// int main(int argc, char** argv) {

//     // if(strcmp(argv[1], "on") == 0){
//     //     set_playback_channel("default", "Master", true);  // 启用
//     // }
//     // if(strcmp(argv[1], "off") == 0){
//     //     set_playback_channel("default", "Master", false); // 禁用
//     // }

//     // printf("采集音量：%d\n", get_capture_volume("hw:0", "Capture"));
//     // printf("新采集音量：%d\n", set_capture_volume("hw:0", "Capture", atoi(argv[1])));
//     printf("回放音量：%d\n", get_playback_volume("hw:0", "Master"));
//     printf("新回放音量：%d\n", set_playback_volume("hw:0", "Master", atoi(argv[1])));

//     return 0;
// }




